import java.util.ArrayList;
import java.util.Scanner;
//注释1
// 主类  
public class PersonalBillManager {
    // 账单类  
    static class Bill {
        String date;
        double amount;
        String category;
        String note;

        public Bill(String date, double amount, String category, String note) {
            this.date = date;
            this.amount = amount;
            this.category = category;
            this.note = note;
        }
    }

    // 收入管理类  
    static class IncomeManager {
        private final ArrayList<Bill> incomes = new ArrayList<>();

        public void recordIncome(String date, double amount, String category, String note) {
            if (amount <= 0) {
                System.out.println("错误：收入金额必须为正数！");
                return;
            }
            incomes.add(new Bill(date, amount, category, note));
            System.out.println("收入已成功记录！");
        }

        public ArrayList<Bill> getIncomes() {
            return incomes;
        }
    }

    // 支出管理类  
    static class ExpenseManager {
        private final ArrayList<Bill> expenses = new ArrayList<>();

        public void recordExpense(String date, double amount, String category, String note) {
            if (amount <= 0) {
                System.out.println("错误：支出金额必须为正数！");
                return;
            }
            expenses.add(new Bill(date, amount, category, note));
            System.out.println("支出已成功记录！");
        }

        public ArrayList<Bill> getExpenses() {
            return expenses;
        }
    }


    // 账单查询类  
    static class BillQuery {
        public void viewAllBills(IncomeManager incomeManager, ExpenseManager expenseManager) {
            System.out.println("\n所有账单：");
            System.out.println("收入：");
            for (Bill bill : incomeManager.getIncomes()) {
                System.out.printf("日期: %s, 金额: %.2f, 类别: %s, 备注: %s%n", bill.date, bill.amount, bill.category, bill.note);
            }
            System.out.println("支出：");
            for (Bill bill : expenseManager.getExpenses()) {
                System.out.printf("日期: %s, 金额: %.2f, 类别: %s, 备注: %s%n", bill.date, bill.amount, bill.category, bill.note);
            }
        }

        public void queryBills(String queryDate, String startDate, String endDate, String queryCategory, IncomeManager incomeManager, ExpenseManager expenseManager) {
            System.out.println("\n查询结果：");
            // 查询收入  
            for (Bill bill : incomeManager.getIncomes()) {
                if (matchesQuery(bill, queryDate, startDate, endDate, queryCategory)) {
                    System.out.printf("收入 - 日期: %s, 金额: %.2f, 类别: %s, 备注: %s%n", bill.date, bill.amount, bill.category, bill.note);
                }
            }
            // 查询支出  
            for (Bill bill : expenseManager.getExpenses()) {
                if (matchesQuery(bill, queryDate, startDate, endDate, queryCategory)) {
                    System.out.printf("支出 - 日期: %s, 金额: %.2f, 类别: %s, 备注: %s%n", bill.date, bill.amount, bill.category, bill.note);
                }
            }
        }

        private boolean matchesQuery(Bill bill, String queryDate, String startDate, String endDate, String queryCategory) {
            boolean matches = true;
            if (queryDate != null && !queryDate.equals(bill.date)) {
                matches = false;
            }
            if (startDate != null && startDate.compareTo(bill.date) > 0) {
                matches = false;
            }
            if (endDate != null && endDate.compareTo(bill.date) < 0) {
                matches = false;
            }
            if (queryCategory != null && !queryCategory.equals(bill.category)) {
                matches = false;
            }
            return matches;
        }
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        IncomeManager incomeManager = new IncomeManager();
        ExpenseManager expenseManager = new ExpenseManager();
        BillQuery billQuery = new BillQuery();
        BudgetManager budgetManager = new BudgetManager();

        while (true) {
            System.out.println("\n=================================");
            System.out.println("欢迎使用个人账单管理系统");
            System.out.println("=================================");
            System.out.println("请选择操作：");
            System.out.println("1. 记录收入");
            System.out.println("2. 记录支出");
            System.out.println("3. 查看所有账单");
            System.out.println("4. 查询账单");
            System.out.println("5. 设置月度预算");
            System.out.println("6. 查看月度统计报告");
            System.out.println("7. 退出系统");
            System.out.print("请输入选项序号：");

            String choice = scanner.nextLine();

            switch (choice) {
                case "1":
                    System.out.println("请输入收入信息：");
                    System.out.print("日期（YYYY-MM-DD）：");
                    String incomeDate = scanner.nextLine();
                    System.out.print("金额：");
                    double incomeAmount = Double.parseDouble(scanner.nextLine());
                    System.out.print("类别（如工资、奖金等）：");
                    String incomeCategory = scanner.nextLine();
                    System.out.print("备注：");
                    String incomeNote = scanner.nextLine();
                    incomeManager.recordIncome(incomeDate, incomeAmount, incomeCategory, incomeNote);
                    break;

                case "2":
                    System.out.println("请输入支出信息：");
                    System.out.print("日期（YYYY-MM-DD）：");
                    String expenseDate = scanner.nextLine();
                    System.out.print("金额：");
                    double expenseAmount = Double.parseDouble(scanner.nextLine());
                    System.out.print("类别（如餐饮、交通、购物等）：");
                    String expenseCategory = scanner.nextLine();
                    System.out.print("备注：");
                    String expenseNote = scanner.nextLine();
                    expenseManager.recordExpense(expenseDate, expenseAmount, expenseCategory, expenseNote);
                    break;

                case "3":
                    billQuery.viewAllBills(incomeManager, expenseManager);
                    break;

                case "4":
                    System.out.print("请输入查询日期（YYYY-MM-DD，留空表示不按日期查询）：");
                    String queryDate = scanner.nextLine().isEmpty() ? null : scanner.nextLine();
                    System.out.print("请输入起始日期（YYYY-MM-DD，留空表示不按起始日期查询）：");
                    String startDate = scanner.nextLine().isEmpty() ? null : scanner.nextLine();
                    System.out.print("请输入结束日期（YYYY-MM-DD，留空表示不按结束日期查询）：");
                    String endDate = scanner.nextLine().isEmpty() ? null : scanner.nextLine();
                    System.out.print("请输入类别（留空表示不按类别查询）：");
                    String queryCategory = scanner.nextLine().isEmpty() ? null : scanner.nextLine();
                    billQuery.queryBills(queryDate, startDate, endDate, queryCategory, incomeManager, expenseManager);
                    break;

                case "5":
                    System.out.print("请输入月度预算金额：");
                    double budgetAmount = Double.parseDouble(scanner.nextLine());
                    budgetManager.setBudget(budgetAmount);
                    break;

                case "6":
                    double remainingBudget = budgetManager.calculateRemainingBudget(expenseManager);
                    double totalIncome = incomeManager.getIncomes().stream().mapToDouble(bill -> bill.amount).sum();
                    double totalExpense = expenseManager.getExpenses().stream().mapToDouble(bill -> bill.amount).sum();
                    System.out.printf("本月总收入: %.2f, 总支出: %.2f, 剩余预算: %.2f%n", totalIncome, totalExpense, remainingBudget);
                    break;

                case "7":
                    System.out.println("感谢使用个人账单管理系统，再见！");
                    scanner.close();
                    return;

                default:
                    System.out.println("错误：无效的选项，请重新选择！");
            }

            // 提示用户按任意键返回主菜单  
            System.out.println("按任意键返回主菜单...");
            scanner.nextLine();
        }
    }
}
